#include "httphelper.h"
#include <QDebug>
#include <QJsonArray>
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonValue>
#include <mutex>
#include<QUrl>

std::unique_ptr<HttpHelper> HttpHelper::instance_=nullptr;
#define SERVER_URL "http://26.70.38.61:9520/"

HttpHelper *HttpHelper::instance()
{
    static std::once_flag flag;
    std::call_once(flag,[&](){
        instance_.reset(new HttpHelper());
    });
    return instance_.get();
}

HttpHelper::~HttpHelper()
{
    if(networkManage)
    {
        delete networkManage;
        networkManage=nullptr;
    }
}

void HttpHelper::slot_GetmediaInfo()
{
    sendRequest(MEDIALIST,false);
}

void HttpHelper::slot_Register(const QVariantMap &infomap)
{
    QJsonObject paramsObj;
    paramsObj[""]=QJsonObject();
    QJsonObject rootObj;
    rootObj["creatTime"]="";
    rootObj["updataTime"]="";
    rootObj["params"]=paramsObj;
    rootObj["userId"]=0;
    rootObj["userName"]=infomap["userName"].toString();
    rootObj["nickName"]=infomap["nickName"].toString();
    rootObj["passwd"]=infomap["passwd"].toString();
    //qjsonobject转为jsondocument
    QJsonDocument doc(rootObj);
    QByteArray jsondata=doc.toJson(QJsonDocument::Compact);
    sendRequest(REGISTER,true,jsondata);
}

void HttpHelper::slot_Login(const QVariantMap &infomap)
{
    QJsonObject paramsObj;
    paramsObj[""]=QJsonObject();
    QJsonObject rootObj;
    rootObj["creatTime"]="";
    rootObj["updataTime"]="";
    rootObj["params"]=paramsObj;
    rootObj["userId"]=0;
    rootObj["userName"]=infomap["userName"].toString();
    rootObj["nickName"]=infomap["nickName"].toString();
    rootObj["passwd"]=infomap["passwd"].toString();
    //qjsonobject转为jsondocument
    QJsonDocument doc(rootObj);
    QByteArray jsondata=doc.toJson(QJsonDocument::Compact);
    sendRequest(LOGIN,true,jsondata);
}

void HttpHelper::slot_LoginOut(const QVariantMap &infomap)
{
    QJsonObject rootObj;
    QJsonDocument doc(rootObj);
    QByteArray jsondata=doc.toJson(QJsonDocument::Compact);
    sendRequest(LOGINOUT,true,jsondata);
}

void HttpHelper::slot_AddmediaInfo(const QVariantMap &infomap)
{
    QJsonObject paramsObj;
    paramsObj[""]=QJsonObject();
    QJsonObject rootObj;
    rootObj["creatTime"]="";
    rootObj["updataTime"]="";
    rootObj["params"]=paramsObj;
    rootObj["mediaId"]=0;
    rootObj["userId"]=0;
    rootObj["mediaUrl"]=infomap["mediaUrl"].toString();
    rootObj["mediaTitle"]=infomap["mediaTitle"].toString();
    rootObj["orderNum"]=0;
    //qjsonobject转为jsondocument
    QJsonDocument doc(rootObj);
    QByteArray jsondata=doc.toJson(QJsonDocument::Compact);
    sendRequest(ADDMEDIA,true,jsondata);
}

void HttpHelper::slot_EditmediaInfo(const QVariantMap &infomap)
{
    QJsonObject paramsObj;
    paramsObj[""]=QJsonObject();
    QJsonObject rootObj;
    rootObj["creatTime"]="";
    rootObj["updataTime"]="";
    rootObj["params"]=paramsObj;
    rootObj["mediaId"]=0;
    rootObj["userId"]=0;
    rootObj["mediaUrl"]=infomap["mediaUrl"].toString();
    rootObj["mediaTitle"]=infomap["mediaTitle"].toString();
    rootObj["orderNum"]=0;
    //qjsonobject转为jsondocument
    QJsonDocument doc(rootObj);
    QByteArray jsondata=doc.toJson(QJsonDocument::Compact);
    sendRequest(EDITMEDIA,true,jsondata);
}

void HttpHelper::slot_RemovemediaInfo(const QVariantMap &infomap)
{
    QJsonObject paramsObj;
    paramsObj[""]=QJsonObject();
    QJsonObject rootObj;
    rootObj["creatTime"]="";
    rootObj["updataTime"]="";
    rootObj["params"]=paramsObj;
    rootObj["mediaId"]=0;
    rootObj["userId"]=0;
    rootObj["mediaUrl"]=infomap["mediaUrl"].toString();
    rootObj["mediaTitle"]=infomap["mediaTitle"].toString();
    rootObj["orderNum"]=0;
    //qjsonobject转为jsondocument
    QJsonDocument doc(rootObj);
    QByteArray jsondata=doc.toJson(QJsonDocument::Compact);
    sendRequest(REMOVEMEDIA,true,jsondata);
}

void HttpHelper::HandleReply(const QByteArray &data)
{
    QJsonParseError parseError;
    QJsonDocument jsonDoc=QJsonDocument::fromJson(data,&parseError);
    QByteArray jsonstring=jsonDoc.toJson(QJsonDocument::Indented);
    qDebug()<<"json data:"<<jsonstring.constData();
    //检查解析是否有误
    if(parseError.error!=QJsonParseError::NoError)
    {
        qDebug()<<"json解析出错:"<<parseError.errorString()<<"位置"<<parseError.offset;
        return;
    }
    //
    if(jsonDoc.isObject())
    {
        QJsonObject jsonObj=jsonDoc.object();
        bool operationSuccess=(jsonObj["code"].toInt()==200);
        int reponseType=jsonObj["responseType"].toInt();
        if(reponseType!=MEDIALIST)
        {
            if(reponseType==LOGIN&&operationSuccess)
            {
                token=jsonObj["msg"].toString();
            }
            emit sig_Operator(static_cast<REQUESTTYPE>(reponseType),operationSuccess);
        }
        else if(reponseType==MEDIALIST&&operationSuccess)
        {
            QJsonValue dataValue=jsonObj["data"];
            //检查data是否为数组
            QVector<QVariantMap> mediaList;
            if(dataValue.isArray())
            {
                QJsonArray dataArray=dataValue.toArray();
                //遍历数组提取里面的视频url和title
                for(const QJsonValue &itemValue:dataArray)
                {
                    if(itemValue.isObject())
                    {
                        QJsonObject itemObj=itemValue.toObject();
                        QVariantMap mediaItem;
                        if(itemObj.contains("mediaTitle")&&itemObj["mediaTitle"].isString())
                        {
                            mediaItem["mediaTitle"]=itemObj["mediaTitle"].toString();
                        }
                        if(itemObj.contains("mediaUrl")&&itemObj["mediaUrl"].isString())
                        {
                            mediaItem["mediaUrl"]=itemObj["mediaUrl"].toString();
                        }
                        mediaList.append(mediaItem);
                    }
                }
            }
            emit sig_MediaInfo(mediaList);
        }
        if(!operationSuccess)
        {
            qDebug()<<"操作失败"<<jsonObj["msg"].toString();
        }
    }
}

void HttpHelper::onReplyFinish(QNetworkReply *reply)
{
    //获取HTTP状态码
    QVariant statusCode=reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);
    //获取详细错误信息
    QNetworkReply::NetworkError errorType=reply->error();
    QString errorMsg=reply->errorString();
    qDebug()<<"request URL:"<<reply->url().toString();
    qDebug()<<"HTTP status code:"<<statusCode.toInt();
    qDebug()<<"Error Type:"<<errorType;
    qDebug()<<"Error Message:"<<errorMsg;

    QByteArray response=reply->readAll();
    qDebug()<<"response data:"<<QString::fromUtf8(response);

    if(errorType==QNetworkReply::NoError)
    {
        //处理应答
        HandleReply(response);
    }
    else
    {
        switch (errorType) {
        case QNetworkReply::ConnectionRefusedError:
            qDebug()<<"连接拒绝，服务都未启动或者端口未开放";
            break;
        case QNetworkReply::HostNotFoundError:
            qDebug()<<"主机未找到,IP或者DNS错误";
            break;
        case QNetworkReply::TimeoutError:
            qDebug()<<"连接超时";
            break;
        case QNetworkReply::ContentNotFoundError:
            qDebug()<<"连接没有找到，URL错误";
            break;
        default:
            qDebug()<<"其他错误"<<errorMsg;
        }
    }
    reply->deleteLater();//释放请求
}

void HttpHelper::sendGetRequest(const QNetworkRequest &request)
{
    networkManage->get(request);
}

void HttpHelper::sendPostRequest(QNetworkRequest &request, const QByteArray &data)
{
    networkManage->post(request,data);
}

void HttpHelper::sendRequest(const REQUESTTYPE type, bool isPost, const QByteArray data)
{
    QUrl url=QUrl::fromUserInput(requestAddrs[type]);
    if(!url.isValid())
    {
        qDebug()<<"url无效";
        return;
    }
    QNetworkRequest request(url);
    //指定数据为json
    request.setHeader(QNetworkRequest::ContentTypeHeader,"application/json");
    //设置token
    QByteArray authHeader=token.toUtf8();
    request.setRawHeader("Authorization",authHeader);
    isPost ? sendPostRequest(request,data):sendGetRequest(request);
}

HttpHelper::HttpHelper(QObject *parent)
    : QObject(parent)
    ,networkManage(new QNetworkAccessManager(this))//初始化列表
{
    requestAddrs[REGISTER]=QString(SERVER_URL) + "user/register";
    requestAddrs[LOGIN]=QString(SERVER_URL) + "user/login";
    requestAddrs[LOGINOUT]=QString(SERVER_URL) + "user/logout";
    requestAddrs[MEDIALIST]=QString(SERVER_URL) + "media/list";
    requestAddrs[ADDMEDIA]=QString(SERVER_URL) + "media/add";
    requestAddrs[EDITMEDIA]=QString(SERVER_URL) + "media/edit";
    requestAddrs[REMOVEMEDIA]=QString(SERVER_URL) + "media/remove";

    connect(networkManage,&QNetworkAccessManager::finished,this,&HttpHelper::onReplyFinish);
}
